package com.ericsson.smart.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ericsson.smart.UtilityCommon;
import com.ericsson.smart.UtilityDimensionDAO;
import com.ericsson.smart.factory.UtilityDimnDAOFactory;
import com.ericsson.smart.model.Dimension;

@Component
public class FactDAOold {
	//UtilityDimnDAOFactory dimensionDAOFactory = new UtilityDimnDAOFactory();

	private String xDimName = null;

	private String yDimName = null;

	private String zDimName = null;

	private Map<String, Object> xDimDataMap;

	private Map<String, Object> yDimDataMap;

	private Map<String, Object> zDimDataMap;

	// Ideally all these lists should be List<T>
	private List<String> xAxisLowestDimIdList;

	private List<String> yAxisLowestDimIdList;

	private List<String> zAxisLowestDimIdList;

	private String xDimDisplayLevel;

	private List<String> xAxisDisplayLevelIds;

	Map<String, String> groupedXdimIdMap;

	@Autowired
	UtilityDimensionDAO dimensionDAO;
	
	@Autowired
	UtilityCommon utilCommon;
	
	

	public <T> Map<String, Float> fetchReportData(List<Map<String, Object>> dimDataMapList,
			List<String> dimList, String aggregateOperation, boolean nextLevelGroupingRequired,
			String groupByDimensionName, Class<T> genericClass) {

		Map<String, Float> groupedFactDataDisplayLevelWise = null;
		
		if (aggregateOperation == null) {
			System.out.println("ERROR: AGGREGATE Operation specified is: " + aggregateOperation
					+ " .Supported opertions are SUM, AVG, MAX, MIN.");
			return null;
		} else if (aggregateOperation.trim().equals("")) {
			System.out.println("ERROR: AGGREGATE Operation specified is: " + aggregateOperation
					+ " .Supported opertions are SUM, AVG, MAX, MIN.");
			return null;
		} else {
			aggregateOperation = aggregateOperation.trim().toUpperCase();
		}

		if (!aggregateOperation.equals("SUM") && !aggregateOperation.equals("AVG")
				&& !aggregateOperation.equals("MAX") && !aggregateOperation.equals("MIN")) {
			System.out.println("ERROR: The AGGREGATE Operation: " + aggregateOperation
					+ " :is NOT SUPPORTED. Supported opertions are SUM, AVG, MAX, MIN.");
			return null;
		}

		pouplateDimensions(dimDataMapList, dimList);

		if (xDimName != null) {
			xAxisLowestDimIdList = populatelDimIdsOfRequiredLevel(xDimName, xDimDataMap,
					utilCommon.getIdColumnForDimension(xDimName));
		}
		if (yDimName != null) {
			yAxisLowestDimIdList = populatelDimIdsOfRequiredLevel(yDimName, yDimDataMap,
					utilCommon.getIdColumnForDimension(yDimName));
		}
		if (zDimName != null) {
			zAxisLowestDimIdList = populatelDimIdsOfRequiredLevel(zDimName, zDimDataMap,
					utilCommon.getIdColumnForDimension(zDimName));
		}
		//xDimDisplayLevel = getXdimDisplayLevel(xDimName, xDimDataMap, true);
		
//		if(xDimName.equals("DIM_SUBSTATION")) {
//			xDimDisplayLevel = getXdimDisplayLevel(xDimName, xDimDataMap, false);
//		} else {
//			xDimDisplayLevel = getXdimDisplayLevel(xDimName, xDimDataMap, true);
//		}
		
		xDimDisplayLevel = getXdimDisplayLevel(xDimName, xDimDataMap, nextLevelGroupingRequired);

		xAxisDisplayLevelIds = getDisplayLevelIds(xDimName, xDimDataMap, xDimDisplayLevel);
		// System.out.println("X-AXIS Display Level ID: " + xAxisDisplayLevelIds);

		groupedXdimIdMap = groupXaxisIdsByDisplayLevel(xDimName, xDimDataMap, xAxisDisplayLevelIds);
		// System.out.println("X-AXIS ID-Display Level Grouping: " + groupedXdimIdMap);

		
		// ??? - This aggregation opertaion should come from Report configuration as passed here as
		// input, Some SQL level translation may be required to perform like AVG for AVREAGE, MAX
		// from MAXIMUM, MIN for MINIMUM
		if (zDimName == null) {
			Map<String, String> factTableValueMap = getDataFromFactTable(xDimName,
					xAxisLowestDimIdList, yDimName, yAxisLowestDimIdList);
			groupedFactDataDisplayLevelWise = groupFactTableDataDisplayLabelWise(
					aggregateOperation, factTableValueMap, groupedXdimIdMap, xDimName,
					xDimDisplayLevel, xAxisDisplayLevelIds, true);
			// System.out.println("FINAL-DATA: " + groupedFactDataDisplayLevelWise);
			//return groupedFactDataDisplayLevelWise;
		} else {
//			Commented for testing			
//			Map<String, Float> factTableValueMap = getDataFromFactTable(xDimName,
//					xAxisLowestDimIdList, yDimName, yAxisLowestDimIdList, zDimName,
//					zAxisLowestDimIdList);
//			return factTableValueMap;
			
			Map<String, String> factTableValueMap = getDataFromFactTableMod(xDimName,
					xAxisLowestDimIdList, yDimName, yAxisLowestDimIdList, zDimName,
					zAxisLowestDimIdList,xDimName);
			groupedFactDataDisplayLevelWise = groupFactTableDataDisplayLabelWise(
					aggregateOperation, factTableValueMap, groupedXdimIdMap, xDimName,
					xDimDisplayLevel, xAxisDisplayLevelIds, false);
			//return groupedFactDataDisplayLevelWise;
		}
		
		if(groupByDimensionName.equals(dimList.get(0))) {
			return groupedFactDataDisplayLevelWise;
		} else {
			return groupedFactDataDisplayLevelWise;
		}
	}

	/*
	public <T> Map<String, Float> fetchReportData(List<Map<String, Object>> dimDataMapList,
			List<String> dimList, String aggregateOperation, boolean nextLevelGroupingRequired,
			String groupByDimension, Class<T> genericClass) {

		if (aggregateOperation == null) {
			System.out.println("ERROR: AGGREGATE Operation specified is: " + aggregateOperation
					+ " .Supported opertions are SUM, AVG, MAX, MIN.");
			return null;
		} else if (aggregateOperation.trim().equals("")) {
			System.out.println("ERROR: AGGREGATE Operation specified is: " + aggregateOperation
					+ " .Supported opertions are SUM, AVG, MAX, MIN.");
			return null;
		} else {
			aggregateOperation = aggregateOperation.trim().toUpperCase();
		}

		if (!aggregateOperation.equals("SUM") && !aggregateOperation.equals("AVG")
				&& !aggregateOperation.equals("MAX") && !aggregateOperation.equals("MIN")) {
			System.out.println("ERROR: The AGGREGATE Operation: " + aggregateOperation
					+ " :is NOT SUPPORTED. Supported opertions are SUM, AVG, MAX, MIN.");
			return null;
		}

		pouplateDimensions(dimDataMapList, dimList);

		if (xDimName != null) {
			xAxisLowestDimIdList = populatelDimIdsOfRequiredLevel(xDimName, xDimDataMap,
					utilCommon.getIdColumnForDimension(xDimName));
		}
		if (yDimName != null) {
			yAxisLowestDimIdList = populatelDimIdsOfRequiredLevel(yDimName, yDimDataMap,
					utilCommon.getIdColumnForDimension(yDimName));
		}
		if (zDimName != null) {
			zAxisLowestDimIdList = populatelDimIdsOfRequiredLevel(zDimName, zDimDataMap,
					utilCommon.getIdColumnForDimension(zDimName));
		}
		//xDimDisplayLevel = getXdimDisplayLevel(xDimName, xDimDataMap, true);
		
//		if(xDimName.equals("DIM_SUBSTATION")) {
//			xDimDisplayLevel = getXdimDisplayLevel(xDimName, xDimDataMap, false);
//		} else {
//			xDimDisplayLevel = getXdimDisplayLevel(xDimName, xDimDataMap, true);
//		}
		
		xDimDisplayLevel = getXdimDisplayLevel(xDimName, xDimDataMap, nextLevelGroupingRequired);

		xAxisDisplayLevelIds = getDisplayLevelIds(xDimName, xDimDataMap, xDimDisplayLevel);
		// System.out.println("X-AXIS Display Level ID: " + xAxisDisplayLevelIds);

		groupedXdimIdMap = groupXaxisIdsByDisplayLevel(xDimName, xDimDataMap, xAxisDisplayLevelIds);
		// System.out.println("X-AXIS ID-Display Level Grouping: " + groupedXdimIdMap);

		// ??? - This aggregation opertaion should come from Report configuration as passed here as
		// input, Some SQL level translation may be required to perform like AVG for AVREAGE, MAX
		// from MAXIMUM, MIN for MINIMUM
		if (zDimName == null) {
			Map<String, String> factTableValueMap = getDataFromFactTable(xDimName,
					xAxisLowestDimIdList, yDimName, yAxisLowestDimIdList);
			Map<String, Float> groupedFactDataDisplayLevelWise = groupFactTableDataDisplayLabelWise(
					aggregateOperation, factTableValueMap, groupedXdimIdMap, xDimName,
					xDimDisplayLevel, xAxisDisplayLevelIds, true);
			// System.out.println("FINAL-DATA: " + groupedFactDataDisplayLevelWise);
			return groupedFactDataDisplayLevelWise;
		} else {
//			Commented for testing			
//			Map<String, Float> factTableValueMap = getDataFromFactTable(xDimName,
//					xAxisLowestDimIdList, yDimName, yAxisLowestDimIdList, zDimName,
//					zAxisLowestDimIdList);
//			return factTableValueMap;
			
			Map<String, String> factTableValueMap = getDataFromFactTableMod(xDimName,
					xAxisLowestDimIdList, yDimName, yAxisLowestDimIdList, zDimName,
					zAxisLowestDimIdList,xDimName);
			Map<String, Float> groupedFactDataDisplayLevelWise = groupFactTableDataDisplayLabelWise(
					aggregateOperation, factTableValueMap, groupedXdimIdMap, xDimName,
					xDimDisplayLevel, xAxisDisplayLevelIds, false);
			return groupedFactDataDisplayLevelWise;
		}
	}
	*/
	
	private <T> Map<String, Float> groupFactTableDataDisplayLabelWise(String aggregateOperation,
			Map<String, String> factTableValueMap, Map<String, String> groupedXdimIdMap,
			String xDimName, String xAxisDisplayLevel, List<T> xAxisDisplayLevelIds, boolean showZeroData) {

		Map<String, Float> groupedFactDataDisplayLevelWise = new HashMap<String, Float>();
		Map<String, Float> avgFactDataDisplayLevelWise = new HashMap<String, Float>();
		String xAxisDisplayLevelData;
		Float aggregateValue = 0f;
		Float singleValue = 0f;

		if (factTableValueMap != null) {
			if(showZeroData) {
				for (int i = 0; i < xAxisDisplayLevelIds.size(); i++) {
					groupedFactDataDisplayLevelWise.put(xAxisDisplayLevelIds.get(i) + "",
							aggregateValue);
				}
			}
			for (Entry<String, String> factTableValue : factTableValueMap.entrySet()) {
				if (groupedXdimIdMap.containsKey(factTableValue.getKey().trim())) {
					xAxisDisplayLevelData = groupedXdimIdMap.get(factTableValue.getKey().trim());
					singleValue = Float.parseFloat(factTableValue.getValue());
					if (groupedFactDataDisplayLevelWise.containsKey(xAxisDisplayLevelData)) {
						aggregateValue = groupedFactDataDisplayLevelWise.get(xAxisDisplayLevelData);
					} else {
						aggregateValue = 0f;
					}
					
					if (aggregateOperation.equalsIgnoreCase("SUM")
							|| aggregateOperation.equalsIgnoreCase("AVG")) {
						aggregateValue += singleValue;
					} else if (aggregateOperation.equalsIgnoreCase("MAX")) {
						if (singleValue > aggregateValue) {
							aggregateValue = singleValue;
						}
					} else if (aggregateOperation.equalsIgnoreCase("MIN")) {
						if (singleValue < aggregateValue) {
							aggregateValue = singleValue;
						}
					}
					groupedFactDataDisplayLevelWise.put(xAxisDisplayLevelData, aggregateValue);
				} else {
					System.out.println("ERROR: Fact Table data: " + factTableValue.getValue()
							+ " : CAN'T be mapped to x-Axis Dipslay Level as mapping of: "
							+ utilCommon.getIdColumnForDimension(xDimName) + " = "
							+ factTableValue.getKey() + " To X-Axis Display Level = "
							+ xAxisDisplayLevel + " is NOT FOUND");
				}
			}
			if (aggregateOperation.equalsIgnoreCase("AVG")) {
				Iterator<String> itr = groupedFactDataDisplayLevelWise.keySet().iterator();
				String key;
				while (itr.hasNext()) {
					key = (String) itr.next();
					avgFactDataDisplayLevelWise.put(key, groupedFactDataDisplayLevelWise.get(key)
							/ xAxisDisplayLevelIds.size());
				}
				return avgFactDataDisplayLevelWise;
			} else {
				return groupedFactDataDisplayLevelWise;
			}
		} else {
			return null;
		}
	}

	private Map<String, String> getDataFromFactTable(String xDimName,
			List<String> xAxisLowestDimIdList, String yDimName, List<String> yAxisLowestDimIdList) {

		String tableName = "FACT_METER_TABLE";
		String aggregateColumn = "AVG_CONSUMPTION";
		String aggregateOperation = "SUM";

		ArrayList<String> outputColumnList = new ArrayList<String>();
		outputColumnList.add(utilCommon.getIdColumnForDimension(xDimName));

		ArrayList<String> groupByColumnList = new ArrayList<String>();
		groupByColumnList.add(utilCommon.getIdColumnForDimension(xDimName));

		Map<String, List<String>> inCriteriaMap = new HashMap<String, List<String>>();
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(xDimName),
				xAxisLowestDimIdList);
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(yDimName),
				yAxisLowestDimIdList);

		Map<String, String> factTableValueMap = dimensionDAO.getDataFromFactTable(tableName,
				aggregateOperation, aggregateColumn, outputColumnList, null, inCriteriaMap,
				groupByColumnList, true);
		return factTableValueMap;
	}

	private <T> Map<String, List<T>> bindXdimDisplayLevelAndIds(String xDimDisplayLevel,
			List<T> xAxisDisplayLevelIds) {
		Map<String, List<T>> bindingMap = new HashMap<String, List<T>>();
		bindingMap.put(xDimDisplayLevel, xAxisDisplayLevelIds);
		return bindingMap;
	}

	private <T> Map<String, String> groupXaxisIdsByDisplayLevel(String dimName,
			Map<String, Object> dimDataMap, List<T> xAxisDisplayLevelIds) {
		System.out.println("Inside groupXaxisIdsByDisplayLevel() method...");
		String tableName = utilCommon.getTableForDimension(dimName);
		Map<String, List<T>> xdimDisplayLevelAndIdsBindingMap = bindXdimDisplayLevelAndIds(
				xDimDisplayLevel, xAxisDisplayLevelIds);

		ArrayList<String> outputColumnList = new ArrayList<String>();
		outputColumnList.add(utilCommon.getIdColumnForDimension(dimName));
		outputColumnList.add(xDimDisplayLevel);

		return dimensionDAO.getResultData(tableName, outputColumnList, dimDataMap,
				xdimDisplayLevelAndIdsBindingMap, true);
	}

	private <T> List<T> getDisplayLevelIds(String dimName, Map<String, Object> dimDataMap,
			String dispLevelName) {
		List<T> lowerLevelDimIdList = populatelDimIdsOfRequiredLevel(dimName, dimDataMap,
				dispLevelName);
		return lowerLevelDimIdList;
	}

	@SuppressWarnings("unchecked")
	private String getXdimDisplayLevel(String dimName, Map<String, Object> dimDataMap, boolean nextLevelGroupingRequired) {
		//ArrayList<String> dimList = new ArrayList<String>(dimDataMap.keySet());
		ArrayList<String> dimList = null;
		System.out.println("Inside getXdimDisplayLevel() method...");
		if(dimDataMap!=null) {
			dimList = new ArrayList<String>(dimDataMap.keySet());
		}
		String lowestDimLevelNameFromList = utilCommon
				.getLowestDimLevelFromList(dimName, dimList).toString().trim();
		if(nextLevelGroupingRequired) {
			return utilCommon.getNextHierarchyLevelName(dimName,
					lowestDimLevelNameFromList);
		} else {
			return lowestDimLevelNameFromList;
		}
		
	}

	// if dimLevelName not specified it will return Ids based on the lowestLevel
	@SuppressWarnings("unchecked")
	private <T> List<T> populatelDimIdsOfRequiredLevel(String dimName,
			Map<String, Object> dimDataMap, String dimLevelName) {
		//dimensionDAO = dimensionDAOFactory.getDimensionDAO(dimName);
		if (dimLevelName == null) {
			// System.out.println("zzz-1-" + dimName + ":" + dimDataMap + ":" + dimLevelName);
			return (List<T>) dimensionDAO
					.getDynamicDistinctList(dimName, utilCommon
							.getIdColumnForDimension(dimName), String.class, dimDataMap, true);
		} else {
			// System.out.println("zzz-2-" + dimName + ":" + dimDataMap + ":" + dimLevelName);
			return (List<T>) dimensionDAO.getDynamicDistinctList(dimName, dimLevelName,
					String.class, dimDataMap, true);
		}
	}

	private void pouplateDimensions(List<Map<String, Object>> dimDataMapList, List<String> dimList) {
		for (int i = 0; i < dimDataMapList.size(); i++) {
			if (i == 0) {
				xDimName = dimList.get(i);
				xDimDataMap = dimDataMapList.get(i);
			} else if (i == 1) {
				yDimName = dimList.get(i);
				yDimDataMap = dimDataMapList.get(i);
			} else if (i == 2) {
				zDimName = dimList.get(i);
				zDimDataMap = dimDataMapList.get(i);
			}
			// System.out.println("yyy-" + dimList.get(i) + " : & : " + dimDataMapList.get(i));
		}
	}

	public <T> Map<String, Float> fetchReportDataMod(List<Map<String, Object>> dimDataMapList,
			List<String> dimList, String aggregateOperation, Class<T> genericClass) {

		if (aggregateOperation == null) {
			System.out.println("ERROR: AGGREGATE Operation specified is: " + aggregateOperation
					+ " .Supported opertions are SUM, AVG, MAX, MIN.");
			return null;
		} else if (aggregateOperation.trim().equals("")) {
			System.out.println("ERROR: AGGREGATE Operation specified is: " + aggregateOperation
					+ " .Supported opertions are SUM, AVG, MAX, MIN.");
			return null;
		} else {
			aggregateOperation = aggregateOperation.trim().toUpperCase();
		}

		if (!aggregateOperation.equals("SUM") && !aggregateOperation.equals("AVG")
				&& !aggregateOperation.equals("MAX") && !aggregateOperation.equals("MIN")) {
			System.out.println("ERROR: The AGGREGATE Operation: " + aggregateOperation
					+ " :is NOT SUPPORTED. Supported opertions are SUM, AVG, MAX, MIN.");
			return null;
		}

		pouplateDimensions(dimDataMapList, dimList);

		if (xDimName != null) {
			xAxisLowestDimIdList = populatelDimIdsOfRequiredLevel(xDimName, xDimDataMap,
					utilCommon.getIdColumnForDimension(xDimName));
		}
		if (yDimName != null) {
			yAxisLowestDimIdList = populatelDimIdsOfRequiredLevel(yDimName, yDimDataMap,
					utilCommon.getIdColumnForDimension(yDimName));
		}
		if (zDimName != null) {
			zAxisLowestDimIdList = populatelDimIdsOfRequiredLevel(zDimName, zDimDataMap,
					utilCommon.getIdColumnForDimension(zDimName));
		}
		xDimDisplayLevel = getXdimDisplayLevel(xDimName, xDimDataMap, true);

		xAxisDisplayLevelIds = getDisplayLevelIds(xDimName, xDimDataMap, xDimDisplayLevel);
		// System.out.println("X-AXIS Display Level ID: " + xAxisDisplayLevelIds);

		groupedXdimIdMap = groupXaxisIdsByDisplayLevel(xDimName, xDimDataMap, xAxisDisplayLevelIds);
		// System.out.println("X-AXIS ID-Display Level Grouping: " + groupedXdimIdMap);

		// ??? - This aggregation opertaion should come from Report configuration as passed here as
		// input, Some SQL level translation may be required to perform like AVG for AVREAGE, MAX
		// from MAXIMUM, MIN for MINIMUM

		Map<String, Float> factTableValueMap = getDataFromFactTableMod(xDimName,
				xAxisLowestDimIdList, yDimName, yAxisLowestDimIdList);
		return factTableValueMap;

		// Map<String, Float> groupedFactDataDisplayLevelWise = groupFactTableDataDisplayLabelWise(
		// aggregateOperation, factTableValueMap, groupedXdimIdMap, xDimName,
		// xDimDisplayLevel, xAxisDisplayLevelIds);
		// System.out.println("FINAL-DATA: " + groupedFactDataDisplayLevelWise);
	}

	public <T> Map<String, Float> fetchReportDataMod1(List<Map<String, Object>> dimDataMapList,
			List<String> dimList, String aggregateOperation, Class<T> genericClass) {

		if (aggregateOperation == null) {
			System.out.println("ERROR: AGGREGATE Operation specified is: " + aggregateOperation
					+ " .Supported opertions are SUM, AVG, MAX, MIN.");
			return null;
		} else if (aggregateOperation.trim().equals("")) {
			System.out.println("ERROR: AGGREGATE Operation specified is: " + aggregateOperation
					+ " .Supported opertions are SUM, AVG, MAX, MIN.");
			return null;
		} else {
			aggregateOperation = aggregateOperation.trim().toUpperCase();
		}

		if (!aggregateOperation.equals("SUM") && !aggregateOperation.equals("AVG")
				&& !aggregateOperation.equals("MAX") && !aggregateOperation.equals("MIN")) {
			System.out.println("ERROR: The AGGREGATE Operation: " + aggregateOperation
					+ " :is NOT SUPPORTED. Supported opertions are SUM, AVG, MAX, MIN.");
			return null;
		}

		pouplateDimensions(dimDataMapList, dimList);

		if (xDimName != null) {
			xAxisLowestDimIdList = populatelDimIdsOfRequiredLevel(xDimName, xDimDataMap,
					utilCommon.getIdColumnForDimension(xDimName));
		}
		if (yDimName != null) {
			yAxisLowestDimIdList = populatelDimIdsOfRequiredLevel(yDimName, yDimDataMap,
					utilCommon.getIdColumnForDimension(yDimName));
		}
		if (zDimName != null) {
			zAxisLowestDimIdList = populatelDimIdsOfRequiredLevel(zDimName, zDimDataMap,
					utilCommon.getIdColumnForDimension(zDimName));
		}
		
		xDimDisplayLevel = getXdimDisplayLevel(zDimName, zDimDataMap, false);
		System.out.println("X-AXIS ID-Display Level: " +xDimDisplayLevel);

		xAxisDisplayLevelIds = getDisplayLevelIds(zDimName, zDimDataMap, xDimDisplayLevel);
		System.out.println("X-AXIS Display Level ID: " + xAxisDisplayLevelIds);

		groupedXdimIdMap = groupXaxisIdsByDisplayLevel(zDimName, zDimDataMap, xAxisDisplayLevelIds);
		System.out.println("X-AXIS ID-Display Level Grouping: " + groupedXdimIdMap);

		// ??? - This aggregation opertaion should come from Report configuration as passed here as
		// input, Some SQL level translation may be required to perform like AVG for AVREAGE, MAX
		// from MAXIMUM, MIN for MINIMUM

		/*
		 * Map<String, Float> factTableValueMap = getDataFromFactTableMod(xDimName,
		 * xAxisLowestDimIdList, yDimName, yAxisLowestDimIdList); return factTableValueMap;
		 */

		/*
		System.out.println("X-DIM DATA MAP: " +xDimDataMap);
		for(String str:xAxisLowestDimIdList) {
			System.out.println("X-AXIS:"+str);
		}
		
		System.out.println("Y-DIM DATA MAP: " +yDimDataMap);
		for(String str:yAxisLowestDimIdList) {
			System.out.println("Y-AXIS:"+str);
		}
		
		System.out.println("Z-DIM DATA MAP: " +zDimDataMap);
		for(String str:zAxisLowestDimIdList) {
			System.out.println("Z-AXIS:"+str);
		}
		*/
		
		Map<String, String> factTableValueMap = getDataFromFactTableMod1(xDimName,
				xAxisLowestDimIdList, yDimName, yAxisLowestDimIdList);

		Map<String, Float> groupedFactDataDisplayLevelWise = groupFactTableDataDisplayLabelWise(
				aggregateOperation, factTableValueMap, groupedXdimIdMap, xDimName,
				xDimDisplayLevel, xAxisDisplayLevelIds, false);
		System.out.println("FINAL-DATA: " + groupedFactDataDisplayLevelWise);
		return groupedFactDataDisplayLevelWise;
	}

	private Map<String, Float> getDataFromFactTableMod(String xDimName,
			List<String> xAxisLowestDimIdList, String yDimName, List<String> yAxisLowestDimIdList) {

		String tableName = "FACT_METER_TABLE";
		String aggregateColumn = "AVG_CONSUMPTION";
		String aggregateOperation = "SUM";

		String groupByDimName = "DIM_SUBSTATION";

		ArrayList<String> outputColumnList = new ArrayList<String>();
		outputColumnList.add(utilCommon.getIdColumnForDimension(groupByDimName));

		ArrayList<String> groupByColumnList = new ArrayList<String>();
		groupByColumnList.add(utilCommon.getIdColumnForDimension(groupByDimName));

		Map<String, List<String>> inCriteriaMap = new HashMap<String, List<String>>();
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(xDimName),
				xAxisLowestDimIdList);
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(yDimName),
				yAxisLowestDimIdList);

		Map<String, String> factTableValueMap = dimensionDAO.getDataFromFactTable(tableName,
				aggregateOperation, aggregateColumn, outputColumnList, null, inCriteriaMap,
				groupByColumnList, true);

		Map<String, Float> factTableResultMap = new HashMap<String, Float>();

		for (Entry<String, String> factTableValue : factTableValueMap.entrySet()) {
			factTableResultMap.put(factTableValue.getKey(),
					Float.parseFloat(factTableValue.getValue()));
		}
		return factTableResultMap;
	}

	private Map<String, String> getDataFromFactTableMod1(String xDimName,
			List<String> xAxisLowestDimIdList, String yDimName, List<String> yAxisLowestDimIdList) {

		String tableName = "FACT_METER_TABLE";
		String aggregateColumn = "AVG_CONSUMPTION";
		String aggregateOperation = "SUM";

		String groupByDimName = "DIM_SUBSTATION";

		ArrayList<String> outputColumnList = new ArrayList<String>();
		outputColumnList.add(utilCommon.getIdColumnForDimension(groupByDimName));

		ArrayList<String> groupByColumnList = new ArrayList<String>();
		groupByColumnList.add(utilCommon.getIdColumnForDimension(groupByDimName));

		Map<String, List<String>> inCriteriaMap = new HashMap<String, List<String>>();
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(xDimName),
				xAxisLowestDimIdList);
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(yDimName),
				yAxisLowestDimIdList);

		Map<String, String> factTableValueMap = dimensionDAO.getDataFromFactTable(tableName,
				aggregateOperation, aggregateColumn, outputColumnList, null, inCriteriaMap,
				groupByColumnList, true);

		return factTableValueMap;
	}

	private Map<String, Float> getDataFromFactTable(String xDimName,
			List<String> xAxisLowestDimIdList, String yDimName, List<String> yAxisLowestDimIdList,
			String zDimName, List<String> zAxisLowestDimIdList) {

		String tableName = "FACT_METER_TABLE";
		String aggregateColumn = "AVG_CONSUMPTION";
		String aggregateOperation = "SUM";

		String groupByDimName = "DIM_CUSTOMER";

		ArrayList<String> outputColumnList = new ArrayList<String>();
		outputColumnList.add(utilCommon.getIdColumnForDimension(groupByDimName));

		ArrayList<String> groupByColumnList = new ArrayList<String>();
		groupByColumnList.add(utilCommon.getIdColumnForDimension(groupByDimName));

		Map<String, List<String>> inCriteriaMap = new HashMap<String, List<String>>();
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(xDimName),
				xAxisLowestDimIdList);
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(yDimName),
				yAxisLowestDimIdList);
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(zDimName),
				zAxisLowestDimIdList);

		Map<String, String> factTableValueMap = dimensionDAO.getDataFromFactTable(tableName,
				aggregateOperation, aggregateColumn, outputColumnList, null, inCriteriaMap,
				groupByColumnList, true);

		Map<String, Float> factTableResultMap = new HashMap<String, Float>();

		for (Entry<String, String> factTableValue : factTableValueMap.entrySet()) {
			factTableResultMap.put((factTableValue.getKey().equalsIgnoreCase("1") ? "DOMESTIC"
					: "COMMERCIAL"), Float.parseFloat(factTableValue.getValue()));
		}
		return factTableResultMap;
	}
	
	private Map<String, String> getDataFromFactTableMod(String xDimName,
			List<String> xAxisLowestDimIdList, String yDimName, List<String> yAxisLowestDimIdList,
			String zDimName, List<String> zAxisLowestDimIdList, String groupByDimName) {

		String tableName = "FACT_METER_TABLE";
		String aggregateColumn = "AVG_CONSUMPTION";
		String aggregateOperation = "SUM";

		//String groupByDimName = "DIM_CUSTOMER";

		ArrayList<String> outputColumnList = new ArrayList<String>();
		outputColumnList.add(utilCommon.getIdColumnForDimension(groupByDimName));

		ArrayList<String> groupByColumnList = new ArrayList<String>();
		groupByColumnList.add(utilCommon.getIdColumnForDimension(groupByDimName));

		Map<String, List<String>> inCriteriaMap = new HashMap<String, List<String>>();
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(xDimName),
				xAxisLowestDimIdList);
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(yDimName),
				yAxisLowestDimIdList);
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(zDimName),
				zAxisLowestDimIdList);

		Map<String, String> factTableValueMap = dimensionDAO.getDataFromFactTable(tableName,
				aggregateOperation, aggregateColumn, outputColumnList, null, inCriteriaMap,
				groupByColumnList, true);
		return factTableValueMap;
	}
	
	/*
	private Map<String, Float> getDataFromFactTableMod(String xDimName,
			List<String> xAxisLowestDimIdList, String yDimName, List<String> yAxisLowestDimIdList,
			String zDimName, List<String> zAxisLowestDimIdList, String groupByDimName) {

		String tableName = "FACT_METER_TABLE";
		String aggregateColumn = "AVG_CONSUMPTION";
		String aggregateOperation = "SUM";

		//String groupByDimName = "DIM_CUSTOMER";

		ArrayList<String> outputColumnList = new ArrayList<String>();
		outputColumnList.add(utilCommon.getIdColumnForDimension(groupByDimName));

		ArrayList<String> groupByColumnList = new ArrayList<String>();
		groupByColumnList.add(utilCommon.getIdColumnForDimension(groupByDimName));

		Map<String, List<String>> inCriteriaMap = new HashMap<String, List<String>>();
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(xDimName),
				xAxisLowestDimIdList);
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(yDimName),
				yAxisLowestDimIdList);
		inCriteriaMap.put(utilCommon.getIdColumnForDimension(zDimName),
				zAxisLowestDimIdList);

		Map<String, String> factTableValueMap = dimensionDAO.getDataFromFactTable(tableName,
				aggregateOperation, aggregateColumn, outputColumnList, null, inCriteriaMap,
				groupByColumnList, true);

		Map<String, Float> factTableResultMap = new HashMap<String, Float>();

		if(groupByDimName.equalsIgnoreCase("DIM_CUSTOMER")) {
			for (Entry<String, String> factTableValue : factTableValueMap.entrySet()) {
				factTableResultMap.put((factTableValue.getKey().equalsIgnoreCase("1") ? "DOMESTIC"
						: "COMMERCIAL"), Float.parseFloat(factTableValue.getValue()));
			}
		}

		return factTableResultMap;
	}
	*/
}
